import JSEncrypt from 'jsencrypt';
import Util from '../framework/util';
import _ from "lodash";

if (!String.prototype.endsWith) {
  String.prototype.endsWith = function (searchString, position) {
    var subjectString = this.toString();
    if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
      position = subjectString.length;
    }
    position -= searchString.length;
    var lastIndex = subjectString.lastIndexOf(searchString, position);
    return lastIndex !== -1 && lastIndex === position;
  };
}
if (!String.prototype.startsWith) {
  String.prototype.startsWith = function (searchString, position) {
    position = position || 0;
    return this.substr(position, searchString.length) === searchString;
  };
}
if (!String.prototype.format) {
  String.prototype.format = function (args) {
    if (arguments.length > 0) {
      var result = this;
      if (arguments.length == 1 && typeof (args) == "object") {
        for (var key in args) {
          var reg = new RegExp("({" + key + "})", "g");
          result = result.replace(reg, args[key]);
        }
      } else {
        for (var i = 0; i < arguments.length; i++) {
          var reg = new RegExp("({[" + i + "]})", "g");
          result = result.replace(reg, arguments[i] || "");
        }
      }
      return result;
    } else {
      return this;
    }
  }
}

if (!String.prototype.toHump) {
  String.prototype.toHump = function () {
    let result = this;
    if (result) {
      if (result.indexOf("_") > -1) {
        return result.toLowerCase().replace(/\_(\w)/g, function (all, letter) {
          return letter.toUpperCase();
        });
      } else if (result == result.toUpperCase()) {
        return result.toLowerCase();
      }

    }
    return result;
  }
}

if (!Array.prototype.findLast) {
  Array.prototype.findLast = function (func) {
    return _.findLast(this, func);
  }
}



// Number.prototype.toFixed = function (n) {
//     if (n != undefined && (isNaN(n) || Number(n) > 17 || Number(n) < 0)) {
//         throw new Error("输入正确的精度范围");
//     }
//     // 拆分小数点整数和小数
//     var num = this;
//     var numList = num.toString().split(".");
//     // 整数
//     var iN = numList[0];
//     // 小数
//     var dN = numList[1];
//     n = parseInt(n);
//     if (isNaN(n) || Number(n) === 0) {
//         // 0或者不填的时候，按0来处理
//         if (dN === undefined) {
//             return num + '';
//         }
//         var idN = Number(dN.toString().substr(0, 1));
//         if (idN >= 5) {
//             iN += 1;
//         }
//         return iN;
//     } else {
//         var dNL = dN === undefined ? 0 : dN.length;
//         if (dNL < n) {
//             // 如果小数位不够的话，那就补全
//             var oldN = num + '.';
//             var a = Number(n) - dNL;
//             while (a > 0) {
//                 oldN += '0';
//                 a--;
//             }
//             return oldN;
//         }
//         // 正常
//         var dN1 = Number(dN.toString().substring(0, n));
//         var dN2 = Number(dN.toString().substring(n, n + 1));
//         if (dN2 >= 5) {
//             dN1 += 1;
//         }
//         return iN + '.' + dN1;
//     }
// }

window.numberToFixed = function (num, radix = 2, formatNaN = '') {
  if (num === '' || num === undefined || num === null) {
    return formatNaN;
  }
  let re = num.toFixed(radix);
  if (Math.abs(re) == 0) {
    return Math.abs(re).toFixed(radix);
  } else {
    return re;
  }
}

Array.prototype.distinct = function () {
  var h = {};
  var arr = [];
  for (var i = 0; i < this.length; i++) {
    if (!h[this[i]]) {
      h[this[i]] = true;
      arr.push(this[i]);
    }
  }
  return arr;
}

Math.uuid = function (len, radix) {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
    uuid = [],
    i;
  radix = radix || chars.length;

  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
  } else {
    // rfc4122, version 4 form
    var r;

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';

    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random() * 16;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
  }

  return uuid.join('');
};

// A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
// by minimizing calls to random()
Math.uuidFast = function () {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),
    uuid = new Array(36),
    rnd = 0,
    r;
  for (var i = 0; i < 36; i++) {
    if (i == 8 || i == 13 || i == 18 || i == 23) {
      uuid[i] = '-';
    } else if (i == 14) {
      uuid[i] = '4';
    } else {
      if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0;
      r = rnd & 0xf;
      rnd = rnd >> 4;
      uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
    }
  }
  return uuid.join('');
};

// A more compact, but less performant, RFC4122v4 solution:
Math.uuidCompact = function () {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
};

JSEncrypt.prototype.encryptLong = function (string) {
  var k = this.getKey();
  try {
    var lt = "";
    var ct = "";
    //RSA每次加密117bytes，需要辅助方法判断字符串截取位置
    //1.获取字符串截取点
    var bytes = new Array();
    bytes.push(0);
    var byteNo = 0;
    var len, c;
    len = string.length;
    var temp = 0;
    for (var i = 0; i < len; i++) {
      c = string.charCodeAt(i);
      if (c >= 0x010000 && c <= 0x10FFFF) {
        byteNo += 4;
      } else if (c >= 0x000800 && c <= 0x00FFFF) {
        byteNo += 3;
      } else if (c >= 0x000080 && c <= 0x0007FF) {
        byteNo += 2;
      } else {
        byteNo += 1;
      }
      if ((byteNo % 117) >= 114 || (byteNo % 117) == 0) {
        if (byteNo - temp >= 114) {
          bytes.push(i);
          temp = byteNo;
        }
      }
    }
    //2.截取字符串并分段加密
    if (bytes.length > 1) {
      for (var i = 0; i < bytes.length - 1; i++) {
        var str;
        if (i == 0) {
          str = string.substring(0, bytes[i + 1] + 1);
        } else {
          str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
        }
        var t1 = k.encrypt(str);
        ct += t1;
      };
      if (bytes[bytes.length - 1] != string.length - 1) {
        var lastStr = string.substring(bytes[bytes.length - 1] + 1);
        ct += k.encrypt(lastStr);
      }
      return Util.hexTobase64(ct);
    }
    var t = k.encrypt(string);
    var y = Util.hexTobase64(t);
    return y;
  } catch (ex) {
    return false;
  }
}

JSEncrypt.prototype.decryptLong = function (base64String) {
  var k = this.getKey();
  // var maxLength = ((k.n.bitLength()+7)>>3);
  var MAX_DECRYPT_BLOCK = 128;
  try {
    var ct = "";
    var t1;
    var bufTmp;
    var hexTmp;
    var str = Util.base64ToHex(base64String);
    var buf = Util.hexToBytes(str);
    var inputLen = buf.length;
    //开始长度
    var offSet = 0;
    //结束长度
    var endOffSet = MAX_DECRYPT_BLOCK;

    //分段加密
    while (inputLen - offSet > 0) {
      if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
        bufTmp = buf.slice(offSet, endOffSet);
        hexTmp = Util.bytesToHex(bufTmp);
        t1 = k.decrypt(hexTmp);
        ct += t1;

      } else {
        bufTmp = buf.slice(offSet, inputLen);
        hexTmp = Util.bytesToHex(bufTmp);
        t1 = k.decrypt(hexTmp);
        ct += t1;

      }
      offSet += MAX_DECRYPT_BLOCK;
      endOffSet += MAX_DECRYPT_BLOCK;
    }
    return ct;
  } catch (ex) {
    return false;
  }
};

export default {};
